
//#ifndef Defines_h
//#define Defines_h

#include "Typedef.h"

// For #pragma todo()
#define Stringize( L )     #L
#define MakeString( M, L ) M(L)
#define $Line \ MakeString( Stringize, __LINE__ )
#define TODO \ __FILE__ "(" $Line ") : TODO: "


// This macro will registrate the class and make it available for Activate-class.
// _CPP version needs to be in the .cpp file.
#define REGISTER_CLASS_CPP(TYPE)																											\
	Void __dummy_registrateClass_##TYPE = TYPE::_addClass();																				\
	void TYPE::_static_constructor_##TYPE()																									\

// Thic macro must be declared in every classes that will be supported.
#define REGISTER_ABSTRACT_CLASS(TYPE) 																										\
	public:																																	\
	inline static GC_PTR<Object> _add()																										\
	{																																		\
	throw Riccsson::System::Exception("Can not create an instance of an abstract class.");													\
	}																																		\
	inline static Void _addClass()																											\
	{ 																																		\
		Riccsson::System::Activator::_addClass( Stringize( TYPE ), new Riccsson::System::ClassContainer(&_add, Stringize(TYPE) ) ); 		\
		Riccsson::System::Activator::_addStaticClassConstructor( Stringize( TYPE ), &TYPE::_static_constructor_##TYPE );					\
		return Void(); 																														\
	} 																																		\
	virtual const char* __getClassName() const 																								\
	{ 																																		\
		return Stringize( TYPE ); 																											\
	} 																																		\
	public: static void _static_constructor_##TYPE();																						\
	private:

// Thic macro must be declared in every classes that will be supported.
#define REGISTER_CLASS(TYPE) 																												\
	public:																																	\
	inline static GC_PTR<Object> _add()																										\
	{																																		\
		return GC_PTR<Object>( new TYPE () );																								\
	}																																		\
	inline static Void _addClass()																											\
	{ 																																		\
		Riccsson::System::Activator::_addClass( Stringize( TYPE ), new Riccsson::System::ClassContainer(&_add, Stringize(TYPE) ) ); 		\
		Riccsson::System::Activator::_addStaticClassConstructor( Stringize( TYPE ), &TYPE::_static_constructor_##TYPE );					\
		return Void(); 																														\
	} 																																		\
	virtual const char* __getClassName() const 																								\
	{ 																																		\
		return Stringize( TYPE ); 																											\
	} 																																		\
	public: static void _static_constructor_##TYPE();																						\
	private:

// Thic macro must be declared in every classes that will be supported. Use this when no empty constructor is available.
#define REGISTER_CLASS_NO_DEFAULT_CONSTRUCTOR(TYPE) 																						\
	public:																																	\
	inline static GC_PTR<Object> _add()																										\
	{																																		\
	throw Riccsson::System::Exception("Can not create an instance of an class with no default constructor.");								\
	}																																		\
	inline static Void _addClass()																											\
	{ 																																		\
		Riccsson::System::Activator::_addClass( Stringize( TYPE ), new Riccsson::System::ClassContainer(&_add, Stringize(TYPE) ) ); 		\
		Riccsson::System::Activator::_addStaticClassConstructor( Stringize( TYPE ), &TYPE::_static_constructor_##TYPE );					\
		return Void(); 																														\
	} 																																		\
	virtual const char* __getClassName() const 																								\
	{ 																																		\
		return Stringize( TYPE ); 																											\
	} 																																		\
	public: static void _static_constructor_##TYPE();																						\
	private:

#define REGISTER_CLASS_NO_DEFAULT_CONSTRUCTOR_CPP(TYPE) \
	Void __dummy_registrateClass_##TYPE = TYPE::_addClass();


#define ENABLE_TRACE

#ifdef ENABLE_TRACE
#  ifdef _MSC_VER
#	ifdef Windows
#    include <windows.h>
#    include <sstream>
#    define TRACE(x)                           \
     do {  std::stringstream s; s << "-- Exception: " << (x) << std::endl;     \
           OutputDebugStringA(s.str().c_str()); \
        } while(0)
#	endif
#  else
#    //include <iostream>
#    define TRACE(x)  std::cerr << (x) << std::flush
#  endif        // or std::clog << (x)
#else
#  define TRACE(x)
#endif

// Java is OBJ instance of CLASS.
#define instanceof(OBJ, CLASS) (dynamic_cast<CLASS*>(OBJ) != nullptr)
#define instanceof_const(OBJ, CLASS) (dynamic_cast<const CLASS*>(OBJ) != nullptr)
#define instanceof_cast(OUTPUT, OBJ, CLASS) (( OUTPUT = dynamic_cast<CLASS*>(OBJ) ) != nullptr)

// Abstract is an virtual keyword. Used for abstract methods combined with =0; at the end. Don't works on
// abstract class.
#define abstract virtual

// For easelly skip remove override keyword.
#define override virtual

#ifdef interface
#undef interface
#endif
// For easelly skip change interface to class.
#define interface class

#if Windows
// Sealed class means that the class can not be inherated. In C++ the class will be final.
#define sealed final
#else
#define sealed
#endif

// C# Foreach.
#define foreach for

#ifdef IN
#undef IN
#endif
// Alternative 'IN keyword instead of 'in'. Uses for foreach loopes.
#define IN :

// C# var
#define var auto

// Const
#define readonly const

// Out parameter. (C++ reference)
#define out &
// Reference parameter. (C++ reference)
#define ref &

// Used for ',' inside an template argument.
#define COMMA ,
// Used for :' inside an template argument.
#define COLON :

// Null keyword.
#define null nullptr

// Volatile
#define volatile

// Unsafe
#define unsafe

// Makes the class static. No instanciable class.
// This macro has to be places in the header file.
#define STATIC_CLASS(Class) private: Class() {}

// Riccsson.System Foreach.
#define foreach2(Type, Name, List)																																\
	if(bool moving_obj_##Name = true)																															\
			if(auto enumerator_obj_##Name = List->GetEnumerator())																								\
					if(Type Name = &enumerator_obj_##Name->_dummy_value_ref)																					\
						for(auto obj_raw_obj_##Name = enumerator_obj_##Name->Current;																			\
								moving_obj_##Name != false && (obj_raw_obj_##Name = enumerator_obj_##Name->Current, enumerator_obj_##Name->_dummy_foreach());)	\

//--------------------------------------------
// Copy constructor (Needed for raw struct to get Properties to work).
#define COPY_CONSTRUCTOR(Class)										\
public: void _copy_constructor_decleration_check() {}				\
public: Class& operator =( const Class& other)						\
{																	\
	if (this != &other)												\
	{ 																\
		this->_copy_constructor_clone( other );						\
	} 																\
	return *this; 													\
}																	\
public: Class( volatile const Class& other )						\
{																	\
	_copy_constructor_clone( other );								\
}																	\
public: void _copy_constructor_clone( volatile const Class& other ) \


#if Android
namespace std
{
	typedef decltype(nullptr) nullptr_t;
}
#endif

//#endif
